package com.example.child_protection.service.base;

import com.example.child_protection.dto.base.BaseRequestDTO;
import com.example.child_protection.dto.base.BaseResponseDTO;
import com.example.child_protection.enums.ResponseCodeEnums;
import com.example.child_protection.enums.ServiceActionEnums;
import com.example.child_protection.enums.SexEnums;
import com.example.child_protection.util.InstantiateUtils;
import com.example.child_protection.util.SystemCode;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyBaseService {
    protected final Logger logger = LoggerFactory.getLogger( getClass() );

    public static void setSuccess( BaseResponseDTO response ) {
        ResponseCodeEnums responseCode = ResponseCodeEnums.EXECUTE_SUCCESS;
        response.setSuccess( Boolean.TRUE.booleanValue() );
        response.setExecuted( Boolean.TRUE.booleanValue() );
        response.setResponseCode( responseCode );
        response.setMessage( responseCode.getDisplayName() );
    }

    public final <REQ extends BaseRequestDTO, RES extends BaseResponseDTO> RES service( HttpServletRequest request, HttpServletResponse response, REQ requestDTO,
                                                                                       Class<RES> responseClass, ServiceExecutor<REQ, RES> executor ) {
        RES responseDTO = InstantiateUtils.instantiate( responseClass );
        responseDTO.setSuccess( Boolean.TRUE.booleanValue() );
        Validate.notNull( requestDTO, "request不能为空", new Object[0] );
        // 1.前置处理(钩子方法).
        try {
            executor.beforeProcess( request, response, requestDTO );
        } catch ( Exception e ) {
            this.logger.error( SystemCode.EXCEPTION, "beforeProcess", e );
            responseDTO.setSuccess( true ).setExecuted( false ).setResponseCode( ResponseCodeEnums.BEFORE_HANDLE_EXCEPTION ).setMessage( e.getMessage() );
            return responseDTO;
        }
        // 2.校验.
        try {
            requestDTO.valid();
        } catch ( IllegalArgumentException e ) {
            this.logger.error( SystemCode.EXCEPTION, "valid", e );
            responseDTO.setSuccess( true ).setExecuted( false ).setResponseCode( ResponseCodeEnums.ILLEGAL_ARGUMENT_EXCEPTION ).setMessage( e.getMessage() );
            return responseDTO;
        } catch ( Exception e ) {
            this.logger.error( SystemCode.EXCEPTION, "valid", e );
            responseDTO.setSuccess( true ).setExecuted( false ).setResponseCode( ResponseCodeEnums.VALIDATION_PARAM_EXCEPTION ).setMessage( e.getMessage() );
            return responseDTO;
        }

        // 3.业务处理.
        try {
            responseDTO = executor.process( request, response, requestDTO );
        } catch ( Exception e ) {
            this.logger.error( SystemCode.EXCEPTION, "process", e );
            responseDTO.setSuccess( true ).setExecuted( false ).setResponseCode( ResponseCodeEnums.BIZ_EXCEPTION ).setMessage( e.getMessage() );
            return responseDTO;
        }
        return responseDTO;
    }

    public final <REQ extends BaseRequestDTO, RES extends BaseResponseDTO> RES service(ServiceActionEnums action, REQ requestDTO,
                                                                                       Class<RES> responseClass, ServiceExecutor<REQ, RES> executor ) {
        logger.info( "请求接口{}，请求参数{}" ,action.getDisplayName(),requestDTO.toString());
        RES responseDTO = InstantiateUtils.instantiate( responseClass );
        responseDTO.setSuccess( Boolean.TRUE.booleanValue() );
        Validate.notNull( requestDTO, "request不能为空", new Object[0] );
        requestDTO.valid();
        // 1.前置处理(钩子方法).
        try {
            executor.beforeProcess(  requestDTO );
        } catch ( Exception e ) {
            this.logger.error( SystemCode.EXCEPTION, "beforeProcess", e );
            responseDTO.setSuccess( true ).setExecuted( false ).setResponseCode( ResponseCodeEnums.BEFORE_HANDLE_EXCEPTION ).setMessage( e.getMessage() );
            return responseDTO;
        }
        // 2.校验.
        try {
            requestDTO.valid();
        } catch ( IllegalArgumentException e ) {
            this.logger.error( SystemCode.EXCEPTION, "valid", e );
            responseDTO.setSuccess( true ).setExecuted( false ).setResponseCode( ResponseCodeEnums.ILLEGAL_ARGUMENT_EXCEPTION ).setMessage( e.getMessage() );
            return responseDTO;
        } catch ( Exception e ) {
            this.logger.error( SystemCode.EXCEPTION, "valid", e );
            responseDTO.setSuccess( true ).setExecuted( false ).setResponseCode( ResponseCodeEnums.VALIDATION_PARAM_EXCEPTION ).setMessage( e.getMessage() );
            return responseDTO;
        }

        // 3.业务处理.
        try {
            responseDTO = executor.process(  requestDTO );
        } catch ( Exception e ) {
            this.logger.error( SystemCode.EXCEPTION, "process", e );
            responseDTO.setSuccess( true ).setExecuted( false ).setResponseCode( ResponseCodeEnums.BIZ_EXCEPTION ).setMessage( e.getMessage() );
            return responseDTO;
        }
        logger.info( "请求接口：{}-成功，返回结果{}" ,action.getDisplayName(),responseDTO.toString());
        return responseDTO;
    }
}
